package com.yanx.system.web.api;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.yanx.common.annotation.ApiResult;
import com.yanx.common.annotation.OperationLog;
import com.yanx.common.core.api.BaseApi;
import com.yanx.common.enums.BusinessType;
import com.yanx.common.exception.BusinessException;
import com.yanx.common.security.SecurityUtils;
import com.yanx.common.security.service.TokenService;
import com.yanx.framework.config.YanxConfig;
import com.yanx.system.base.model.dto.SysUserDto;
import com.yanx.system.base.model.vo.SysPostVo;
import com.yanx.system.base.model.vo.SysRoleVo;
import com.yanx.system.base.model.vo.SysUserVo;
import com.yanx.system.base.query.SysUserByIdQry;
import com.yanx.system.web.command.SystemUserEditCmd;
import com.yanx.system.web.infra.utils.FileUploadUtils;
import com.yanx.system.web.infra.utils.MimeTypeUtils;
import com.yanx.system.web.query.SysPostListByUserIdQry;
import com.yanx.system.web.query.SysRoleListByUserIdQry;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 个人信息 接口
 *
 * @author: gotanks
 * @create: 2023-6-6
 */
@Tag(name = "个人信息", description = "个人信息")
@RestController
@RequestMapping(value = "/system/user/profile")
public class SystemProfileApi extends BaseApi {

    @Autowired
    private TokenService tokenService;

    @ApiResult
    @Operation(summary = "个人信息")
    @GetMapping
    public Map<String, Object> profile() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        SysUserVo sysUserVo = queryExecutor.execute(new SysUserByIdQry(userId));
        Map<String, Object> result = BeanUtil.beanToMap(sysUserVo);

        List<SysRoleVo> roleVos = queryExecutor.execute(new SysRoleListByUserIdQry(userId));
        List<SysPostVo> postVos = queryExecutor.execute(new SysPostListByUserIdQry(userId));
        result.put("postGroup", postVos.stream().map(SysPostVo::getPostName).collect(Collectors.toList()));
        result.put("roleGroup", roleVos.stream().map(SysRoleVo::getRoleName).collect(Collectors.toList()));
        return result;
    }

    @OperationLog(title = "个人信息", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "修改用户")
    @PutMapping
    public void updateProfile(@RequestBody SysUserDto user) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        //更新用户信息
        user.setUserId(loginUser.getUserId());
        user.setUserName(loginUser.getUsername());
        user.setPassword(null);
        user.setAvatar(null);
        user.setDeptId(null);
        commandExecutor.execute(new SystemUserEditCmd(user));

        // fixme 更新缓存用户信息
//        loginUser.setNickName(user.getNickName());
//        loginUser.setPhonenumber(user.getPhonenumber());
//        loginUser.setEmail(user.getEmail());
//        loginUser.setSex(user.getSex());
//        tokenService.setLoginUser(loginUser);
    }

    @OperationLog(title = "个人信息", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "重置密码")
    @PutMapping("/updatePwd")
    public void updatePwd(String oldPassword, String newPassword) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String password = loginUser.getPassword();

        if (!SecurityUtils.matchesPassword(oldPassword, password)) {
            throw new BusinessException("修改密码失败，旧密码错误");
        }
        if (SecurityUtils.matchesPassword(newPassword, password)) {
            throw new BusinessException("新密码不能与旧密码相同");
        }

        String encryptPassword = SecurityUtils.encryptPassword(newPassword);

        SysUserDto user = new SysUserDto();
        user.setUserId(loginUser.getUserId());
        user.setPassword(encryptPassword);
        commandExecutor.execute(new SystemUserEditCmd(user));
        // 更新缓存用户密码
        loginUser.setPassword(encryptPassword);
        tokenService.refreshToken(loginUser);
    }

    @OperationLog(title = "用户头像", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "头像上传")
    @PostMapping("/avatar")
    public Map<String, Object> avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
        if (!file.isEmpty()) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            String avatar = FileUploadUtils.upload(YanxConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
            System.out.println(avatar);

            SysUserDto sysUserDto = new SysUserDto();
            sysUserDto.setId(loginUser.getUserId());
            sysUserDto.setAvatar(avatar);
            commandExecutor.execute(new SystemUserEditCmd(sysUserDto));


            // fixme 更新缓存用户头像
//            loginUser.getUser().setAvatar(avatar);
//            tokenService.setLoginUser(loginUser);

            Map<String, Object> result = new HashMap<>();
            result.put("imgUrl", avatar);
            return result;
        }
        throw new BusinessException("上传图片异常，请联系管理员");
    }
}